package com.heima.comment.service.impl;

import com.heima.comment.service.CommentHotService;
import com.heima.comment.service.CommentService;
import com.heima.common.exception.CustomException;
import com.heima.feigns.article.ArticleFeign;
import com.heima.feigns.user.UserFeign;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.comment.dtos.CommentDto;
import com.heima.model.comment.dtos.CommentLikeDto;
import com.heima.model.comment.dtos.CommentSaveDto;
import com.heima.model.comment.pojos.ApComment;
import com.heima.model.comment.pojos.ApCommentLike;
import com.heima.model.comment.vo.ApCommentVo;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.utils.threadlocal.AppThreadLocalUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class CommentServiceimpl implements CommentService {

    @Resource
    ArticleFeign articleFeign;

    @Resource
    UserFeign userFeign;

    @Resource
    MongoTemplate mongoTemplate;

    @Override
    public ResponseResult saveComment(CommentSaveDto dto) {
        //参数校验
        if (dto.getArticleId() == null || StringUtils.isBlank(dto.getContent())) {
            throw new CustomException(AppHttpCodeEnum.PARAM_REQUIRE);
        }

        //判断用户是否登录
        ApUser user = AppThreadLocalUtils.getUser();
        if (user == null) {
            throw new CustomException(AppHttpCodeEnum.NEED_LOGIN);
        }

        //根据文章id查询文章是否存在
        ApArticle apArticle = articleFeign.findByArticleId(dto.getArticleId());
        if (apArticle == null) {
            throw new CustomException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }

        //查询用户是否存在
        ApUser apUser = userFeign.findUserById(Long.valueOf(user.getId()));
        if (apUser == null) {
            throw new CustomException(AppHttpCodeEnum.USER_INEXISTENCE);
        }
        //封装评论信息
        ApComment apComment = new ApComment();
        apComment.setAuthorId(apUser.getId());
        apComment.setAuthorName(apUser.getName());
        apComment.setImage(apUser.getImage());
        apComment.setContent(dto.getContent());
        apComment.setEntryId(dto.getArticleId());
        apComment.setCreatedTime(new Date());
        apComment.setUpdatedTime(new Date());
        apComment.setLikes(0);
        apComment.setReply(0);
        apComment.setType((short) 0);
        apComment.setFlag((short) 0);
        //添加评论
        mongoTemplate.insert(apComment);

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Resource
    CommentHotService commentHotService;

    @Override
    public ResponseResult like(CommentLikeDto dto) {
        //参数校验
        if (dto.getOperation() == null || StringUtils.isBlank(dto.getCommentId())) {
            throw new CustomException(AppHttpCodeEnum.PARAM_REQUIRE);
        }

        //判断用户是否登录
        ApUser user = AppThreadLocalUtils.getUser();
        if (user == null) {
            throw new CustomException(AppHttpCodeEnum.NEED_LOGIN);
        }

        //查询评论是否存在
        ApComment apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);

        if (apComment == null) {
            throw new CustomException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
       // dto.getOperation().intValue() == 0
        if (dto.getOperation()!=null) {
            apComment.setLikes(apComment.getLikes() + 1);
            mongoTemplate.save(apComment);
            //封装点赞数据
            ApCommentLike apCommentLike = new ApCommentLike();
            apCommentLike.setAuthorId(user.getId());
            apCommentLike.setCommentId(apComment.getId());
            apCommentLike.setOperation(dto.getOperation());
            //添加点赞数据
            mongoTemplate.save(apCommentLike);



            commentHotService.hotCommentExecutor(apComment.getEntryId(), apComment);

        } else {  //取消点赞
            apComment.setLikes(apComment.getLikes() - 1 < 0 ? 0 : (apComment.getLikes() - 1));
            mongoTemplate.save(apComment);
            Query query = Query.query(Criteria.where("authorId").is(user.getId()).and("commentId").is(apComment.getId()));
            mongoTemplate.remove(query, ApCommentLike.class);
        }
        //数据返回
        Map<String, Object> resultMap = new HashMap<>();

        resultMap.put("likes", apComment.getLikes());

        return ResponseResult.okResult(resultMap);
    }

    @Override
    public ResponseResult findByArticleId(CommentDto dto) {
        //参数校验
        if (dto == null || dto.getArticleId() == null) {
            throw new CustomException(AppHttpCodeEnum.PARAM_REQUIRE);
        }

        if (dto.getMinDate() == null) {
            dto.setMinDate(new Date());
        }

        dto.checkParam();

        //查询所有评论
        List<ApComment> commentList = mongoTemplate.find(Query.query(Criteria.where("entryId").is(dto.getArticleId()).and("createdTime").lt(dto.getMinDate()))
                .with(Sort.by(Sort.Direction.DESC, "createdTime")).limit(dto.getSize()), ApComment.class);
        //判断用户是否登录
        ApUser user = AppThreadLocalUtils.getUser();
        if (user == null) {
            return ResponseResult.okResult(commentList);
        }

        // 按照点赞数量倒序排列
        List<ApComment> apComments = commentList.stream().sorted(Comparator.comparing(ApComment::getLikes).reversed()).collect(Collectors.toList());

        //查询用户点赞的评论
        List<ApCommentLike> apCommentLikes = mongoTemplate.find(Query.query(Criteria.where("authorId").is(user.getId())), ApCommentLike.class);
        //创建添加用户点赞信息的集合
        ArrayList<ApCommentVo> apCommentVoList = new ArrayList<>();


        for (ApComment apComment : apComments) {

            ApCommentVo apCommentVo = new ApCommentVo();
            BeanUtils.copyProperties(apComment, apCommentVo);

            for (ApCommentLike apCommentLike : apCommentLikes) {
                if (apCommentVo.getId().equals(apCommentLike.getCommentId())) {

                    apCommentVo.setOperation((short) 0);
                }
            }
            apCommentVoList.add(apCommentVo);
        }
        //返回数据
        return ResponseResult.okResult(apCommentVoList);
    }
}
